﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Common;

namespace ImageProcessPlugins
{
    public partial class ScissorForm : Form
    {
        private Bitmap sourceBitmap;

        private ActionType actionType = ActionType.actionNONE;

        private bool withRectangle = false;

        private Point rectangleStart;
        private Point rectangleEnd;
        private Point moveStart;
        private Point moveEnd;
        private Point scaleEnd;
        private PositionToRectangleType scaleDirection;

        private enum ActionType
        {
            actionNONE,
            actionDRAW,
            actionMOVE,
            actionSCALE
        }

        private enum PositionToRectangleType
        {
            OUT,
            IN,
            UP,
            DOWN,
            LEFT,
            RIGHT,
            UP_LEFT,
            UP_RIGHT,
            DOWN_LEFT,
            DOWN_RIGHT
        }

        private PositionToRectangleType GetPositionToRectangleType(int x, int y)
        {
            Point start = view.ImageSpacePointToScreenSpacePoint(rectangleStart);
            Point end = view.ImageSpacePointToScreenSpacePoint(rectangleEnd);
            Point p = view.ImageSpacePointToScreenSpacePoint(new Point(x, y));
            if (start.X < p.X && p.X < end.X && start.Y < p.Y && p.Y < end.Y) return PositionToRectangleType.IN;
            else if (p.X == start.X && p.Y == start.Y) return PositionToRectangleType.UP_LEFT;
            else if (p.X == start.X && p.Y == end.Y) return PositionToRectangleType.DOWN_LEFT;
            else if (p.X == end.X && p.Y == start.Y) return PositionToRectangleType.UP_RIGHT;
            else if (p.X == end.X && p.Y == end.Y) return PositionToRectangleType.DOWN_RIGHT;
            else if (p.X == start.X && start.Y < p.Y && p.Y < end.Y) return PositionToRectangleType.LEFT;
            else if (p.X == end.X && start.Y < p.Y && p.Y < end.Y) return PositionToRectangleType.RIGHT;
            else if (p.Y == start.Y && start.X < p.X && p.X < end.X) return PositionToRectangleType.UP;
            else if (p.Y == end.Y && start.X < p.X && p.X < end.X) return PositionToRectangleType.DOWN;
            else return PositionToRectangleType.OUT;
        }

        public void SetCurrentDoc(Document currentdoc)
        {
            sourceBitmap = currentdoc.GetBitmap();
            Document doc = new Document();
            doc.SetBitmap(sourceBitmap);
            view.SetDocument(doc);
        }

        public ScissorForm()
        {
            InitializeComponent();
            view.Cursor = Cursors.Cross;
            view.EnableMoving = false;
        }

        private void view_ImageMouseDown(int x, int y)
        {
            if (withRectangle)
            {
                PositionToRectangleType type = GetPositionToRectangleType(x, y);
                switch (type)
                {
                    case PositionToRectangleType.IN:
                        moveStart = new Point(x, y);
                        actionType = ActionType.actionMOVE;
                        break;
                    case PositionToRectangleType.OUT:
                        actionType = ActionType.actionNONE;
                        break;
                    default:
                        actionType = ActionType.actionSCALE;
                        scaleDirection = type;
                        break;
                }
            }
            else
            {
                rectangleStart = new Point(x, y);
                actionType = ActionType.actionDRAW;
            }
            view.RefreshOverlay();
        }

        private void view_ImageMouseUp(int x, int y)
        {
            if (actionType == ActionType.actionDRAW) withRectangle = true;
            actionType = ActionType.actionNONE;
            view.Cursor = Cursors.Default;
            view.RefreshOverlay();
        }

        private void view_ImageMouseMove(int x, int y)
        {
            switch (actionType)
            {
                case ActionType.actionNONE:
                    if (withRectangle)
                    {
                        PositionToRectangleType type = GetPositionToRectangleType(x, y);
                        switch (type)
                        {
                            case PositionToRectangleType.OUT:
                                view.Cursor = Cursors.Default;
                                break;
                            case PositionToRectangleType.IN:
                                view.Cursor = Cursors.SizeAll;
                                break;
                            case PositionToRectangleType.UP:
                                view.Cursor = Cursors.SizeNS;
                                break;
                            case PositionToRectangleType.DOWN:
                                view.Cursor = Cursors.SizeNS;
                                break;
                            case PositionToRectangleType.LEFT:
                                view.Cursor = Cursors.SizeWE;
                                break;
                            case PositionToRectangleType.RIGHT:
                                view.Cursor = Cursors.SizeWE;
                                break;
                            case PositionToRectangleType.UP_LEFT:
                                view.Cursor = Cursors.SizeNWSE;
                                break;
                            case PositionToRectangleType.UP_RIGHT:
                                view.Cursor = Cursors.SizeNESW;
                                break;
                            case PositionToRectangleType.DOWN_LEFT:
                                view.Cursor = Cursors.SizeNESW;
                                break;
                            case PositionToRectangleType.DOWN_RIGHT:
                                view.Cursor = Cursors.SizeNWSE;
                                break;
                        }
                    }
                    break;
                case ActionType.actionDRAW:
                    rectangleEnd = new Point(x, y);
                    break;
                case ActionType.actionMOVE:
                    moveEnd = new Point(x, y);
                    break;
                case ActionType.actionSCALE:
                    scaleEnd = new Point(x, y);
                    break;
            }
            view.RefreshOverlay();
        }

        private void view_DrawOverlay(Graphics g, Rectangle imageRect)
        {
            Point start = view.ImageSpacePointToScreenSpacePoint(rectangleStart);
            Point end = view.ImageSpacePointToScreenSpacePoint(rectangleEnd);
            switch (actionType)
            {
                case ActionType.actionNONE:
                case ActionType.actionDRAW:
                    g.DrawRectangle(Pens.Red, new Rectangle(start.X, start.Y, end.X - start.X, end.Y - start.Y));
                    break;
                case ActionType.actionMOVE:
                    Point move1 = view.ImageSpacePointToScreenSpacePoint(moveStart);
                    Point move2 = view.ImageSpacePointToScreenSpacePoint(moveEnd);
                    Point p = new Point(move2.X - move1.X, move2.Y - move1.Y);
                    start = new Point(start.X + p.X, start.Y + p.Y);
                    end = new Point(end.X + p.X, end.Y + p.Y);
                    g.DrawRectangle(Pens.Red, new Rectangle(start.X, start.Y, end.X - start.X, end.Y - start.Y));
                    break;
                case ActionType.actionSCALE:
                    switch (scaleDirection)
                    {
                        case PositionToRectangleType.UP:
                            rectangleStart = new Point(rectangleStart.X, scaleEnd.Y);
                            break;
                        case PositionToRectangleType.DOWN:
                            rectangleEnd = new Point(rectangleEnd.X, scaleEnd.Y);
                            break;
                        case PositionToRectangleType.LEFT:
                            rectangleStart = new Point(scaleEnd.X, rectangleStart.Y);
                            break;
                        case PositionToRectangleType.RIGHT:
                            rectangleEnd = new Point(scaleEnd.X, rectangleEnd.Y);
                            break;
                        case PositionToRectangleType.UP_LEFT:
                            rectangleStart = scaleEnd;
                            break;
                        case PositionToRectangleType.UP_RIGHT:
                            rectangleStart = new Point(rectangleStart.X, scaleEnd.Y);
                            rectangleEnd = new Point(scaleEnd.X, rectangleEnd.Y);
                            break;
                        case PositionToRectangleType.DOWN_LEFT:
                            rectangleStart = new Point(scaleEnd.X, rectangleStart.Y);
                            rectangleEnd = new Point(rectangleEnd.X, scaleEnd.Y);
                            break;
                        case PositionToRectangleType.DOWN_RIGHT:
                            rectangleEnd = scaleEnd;
                            break;
                    }
                    start = view.ImageSpacePointToScreenSpacePoint(rectangleStart);
                    end = view.ImageSpacePointToScreenSpacePoint(rectangleEnd);
                    g.DrawRectangle(Pens.Red, new Rectangle(start.X, start.Y, end.X - start.X, end.Y - start.Y));
                    break;
            }
        }

        private void view_Paint(object sender, PaintEventArgs e)
        {

        }
    }
}
